package com.ytkj.digitalConstruction.service.constructionprocess;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.druid.util.StringUtils;
import com.ytkj.digitalConstruction.dao.constructionplan.ConstructionContentMapper;
import com.ytkj.digitalConstruction.dao.constructionplan.ConstructionPlanContentMapper;
import com.ytkj.digitalConstruction.dao.constructionplan.ConstructionPlanDeviceMapper;
import com.ytkj.digitalConstruction.dao.constructionplan.ConstructionPlanMapper;
import com.ytkj.digitalConstruction.entity.constructionplan.ConstructionContent;
import com.ytkj.digitalConstruction.entity.constructionplan.ConstructionPlan;
import com.ytkj.digitalConstruction.entity.constructionplan.ConstructionPlanContent;
import com.ytkj.digitalConstruction.entity.constructionprocess.ConstructionApproach;
import com.ytkj.digitalConstruction.entity.constructionprocess.ConstructionBase;
import com.ytkj.digitalConstruction.entity.user.User;
import com.ytkj.digitalConstruction.enums.construction.ConstructionResultEnum;
import com.ytkj.digitalConstruction.enums.construction.SpecialProcessEnum;
import com.ytkj.digitalConstruction.exception.CustomException;
import com.ytkj.digitalConstruction.httpbean.constructionprocess.reqbean.PlanAddParam;
import com.ytkj.digitalConstruction.httpbean.constructionprocess.resbean.WholeFlowInfo;

/**
 * 施工计划相关业务操作
 * 
 * @author 宁~
 *
 */
@Service
@Transactional
public class ConstructionPlanService {

	@Autowired
	private ConstructionBaseService constructionBaseService;
	
	@Autowired
	private ConstructionPlanMapper constructionPlanMapper;
	
	@Autowired
	private ConstructionPlanDeviceMapper constructionPlanDeviceMapper;
	
	@Autowired
	private ConstructionContentMapper constructionContentMapper;
	
	@Autowired
	private ConstructionPlanContentMapper constructionPlanContentMapper;
	
	@Autowired
	private SendNoticeService sendNoticeService;
	
	@Autowired
	private ConstructionConcentrateNoticeService constructionConcentrateNoticeService;
	
	private Integer planSetting = 13;
	
	private Integer confirmPlan = 14;
	
	/**
	 * @Description: 添加施工计划
	 * @Title: setPlan 
	 * @param @param planAddParam
	 * @param @return 
	 * @return WholeFlowInfo
	 * @throws
	 */
	public WholeFlowInfo setPlan(PlanAddParam planAddParam, User user){
		constructionBaseService.checkProcess(planAddParam.getFlowId(), planSetting);
		
		// 增加施工计划
		createPlanAddParam(planAddParam, user); 
		constructionPlanMapper.insertSelective(planAddParam);
		ConstructionUtilService.isAddSuccess(planAddParam.getPlanId());
		
		// 增加计划相关的内容、内容关联、设备关联信息
		insertPlanRelevant(planAddParam);
		if(planAddParam.getIsconstruct() == 0) {
			return constructionBaseService.processNextResult(planAddParam.getFlowId(), user, 3, SpecialProcessEnum.CANCEL_CONSTRUCTION);
		}
		return constructionBaseService.processNextResult(planAddParam.getFlowId(),user, 3);
	}
	
	/**
	 * @Description: 补全施工计划
	 * @Title: createPlanAddParam 
	 * @param @param planAddParam
	 * @param @param userId
	 * @param @param state
	 * @param @return 
	 * @return PlanAddParam
	 * @throws
	 */
	public PlanAddParam createPlanAddParam(PlanAddParam planAddParam, User user){
		patchPlan(planAddParam, user);
		planAddParam.setStatus(0);
		return planAddParam;
	}
	
	/**
	 * @Description: 监理确认施工计划
	 * @Title: confirmPlanSupervisor 
	 * @param @param flowId 
	 * @param @return 
	 * @return WholeFlowInfo
	 * @throws
	 */
	public WholeFlowInfo confirmPlanSupervisor(Integer flowId, User user){
		constructionBaseService.checkNowProcess(flowId, confirmPlan);
		
		ConstructionPlan constructionPlan = new ConstructionPlan();
		constructionPlan.setFlowId(flowId);
		constructionPlan.setStatus(1);
		patchPlan(constructionPlan, user);
		ConstructionUtilService.isUpdateSuccess(constructionPlanMapper.updateByFlowIdSelective(constructionPlan));
		
		Integer isConstruction = constructionPlanMapper.selectPlanByFlowId(flowId).getIsconstruct();
		if(isConstruction == 0) { // 不可施工
			return constructionBaseService.processNextResult(flowId,user, 4, SpecialProcessEnum.CANCEL_CONSTRUCTION);
		}
		WholeFlowInfo flowInfo = constructionBaseService.processNextResult(flowId,user, null);
		constructionConcentrateNoticeService.noticeRiskEdc(flowId, flowInfo, user);
		return constructionBaseService.showWholeFlowByFlowId(flowId);
	}

	/**
	 * @Description: 获取指定项目昨日施工计划中的施工内容
	 * @Title: getContentInToday 
	 * @param @param projectId
	 * @param @return 
	 * @return ConstructionContent
	 * @throws
	 */
	public ConstructionContent getTodaysContent(Integer projectId) {
		return constructionContentMapper.selectYesterDayByProjectId(projectId);
	}
	
	/**
	 * @Description: 修改信息，监理确认后只能修改人员车辆设备信息其余不可，指挥部确认后都不可以
	 * @Title: updatePlan 
	 * @param @param planAddParam
	 * @param @return 
	 * @return WholeFlowInfo
	 * @throws
	 */
	public WholeFlowInfo updatePlan(PlanAddParam planAddParam, User user) {
		ConstructionBase base = constructionBaseService.getBaseInfo(planAddParam.getFlowId());
		if(!ConstructionUtilService.checkNowDate(base.getCreateDate())) {
			new CustomException(ConstructionResultEnum.DATE_NOT_TODAY);
		}
		// 进入施工区的申请是否已经审核完成
		boolean isConfirmApproach = constructionBaseService.isConfirmApproach(planAddParam.getFlowId());
		// 监理单位是否已经确认施工计划
		boolean isSupervisorConfirmation = constructionBaseService.isSupervisorConfirmation(planAddParam.getFlowId());
		// 填写施工计划进度是否完成
		boolean isPlanSetted = constructionBaseService.isProcessOver(planAddParam.getFlowId(), planSetting);
		// 是否已经结束或者取消
		boolean isEnd = constructionBaseService.isEnd(planAddParam.getFlowId());
		
		boolean flag = false;
		
		// 已经同意进入施工区的申请   OR 还未提交施工计划  OR 已结束或者已取消
		if(isConfirmApproach || !isPlanSetted || isEnd) {  
			
		}else if(isSupervisorConfirmation) { // 只能修改人员设备车辆信息
			ConstructionPlan constructionPlan = new ConstructionPlan();
			constructionPlan.setPlanId(planAddParam.getPlanId());
			constructionPlan.setPersonNum(planAddParam.getPersonNum());
			constructionPlan.setVehicleNum(planAddParam.getVehicleNum());
			patchPlan(constructionPlan, user);
			ConstructionUtilService.isUpdateSuccess(constructionPlanMapper.updateByPrimaryKeySelective(constructionPlan));
			
			// 删除旧数据并增加新的计划设备关联
			constructionPlanDeviceMapper.deleteByFlowId(planAddParam.getFlowId());
			if(planAddParam.getDeviceIds() != null && planAddParam.getDeviceIds().size() > 0) {
				int result = constructionPlanDeviceMapper.insertByPlan(planAddParam);
				if(result != planAddParam.getDeviceIds().size()){
					throw new CustomException(ConstructionResultEnum.FLOW_ADD_ERROR);
				}
			}
		}else {
			flag = true;
			constructionPlanMapper.deletePlanRelevant(planAddParam.getFlowId());
			patchPlan(planAddParam, user);
			ConstructionPlan constructionPlan = constructionPlanMapper.selectByPrimaryKey(planAddParam.getPlanId());
			constructionPlanMapper.updateByPrimaryKeySelective(planAddParam);
			// 增加计划相关的内容、内容关联、设备关联信息
			insertPlanRelevant(planAddParam);
			if(constructionPlan.getIsconstruct() == 0 && planAddParam.getIsconstruct() == 1) {
				return constructionBaseService.processNextResult(planAddParam.getFlowId(), user, 3, SpecialProcessEnum.UPDATE_CONSTRUCTION_ALLOW);
			}
			else if(constructionPlan.getIsconstruct() == 1 && planAddParam.getIsconstruct() == 0) {
				return constructionBaseService.processNextResult(planAddParam.getFlowId(), user, 3, SpecialProcessEnum.CANCEL_CONSTRUCTION);
			}
		}
		WholeFlowInfo flowInfo = constructionBaseService.showWholeFlowByFlowId(planAddParam.getFlowId());
		if(flag) {
			sendNoticeService.flowNoticeSend(3, flowInfo, user);
		}
		return flowInfo;
	}
	
	/**
	 * @Description: 增加施工计划相关的信息
	 * @Title: insertPlanRelevant 
	 * @param @param planAddParam 
	 * @return void
	 * @throws
	 */
	public void insertPlanRelevant(PlanAddParam planAddParam) {
		// 增加计划设备关联
		addPlanDevice(planAddParam);

		// 增加文本内容及关联信息
		addPlanContent(planAddParam);
	}
	
	/**
	 * @Description: 增加文本内容及关联信息
	 * @Title: addPlanContent 
	 * @param @param planAddParam 
	 * @return void
	 * @throws
	 */
	public void addPlanContent(PlanAddParam planAddParam) {
		if(planAddParam.getConstructionContent() == null
				|| planAddParam.getConstructionContent().size() == 0) {
			return;
		}
		List<ConstructionPlanContent> constructionPlanContents = new ArrayList<>();
		constructionContentMapper.insertByList(planAddParam.getConstructionContent());
		for(ConstructionContent constructionContent : planAddParam.getConstructionContent()) {
			ConstructionUtilService.isAddSuccess(constructionContent.getContentId());
			ConstructionPlanContent planContent = new ConstructionPlanContent();
			planContent.setContentId(constructionContent.getContentId());
			planContent.setFlowId(planAddParam.getFlowId());
			constructionPlanContents.add(planContent);
		}
		
		// 增加计划内容关联信息
		constructionPlanContentMapper.insertByList(constructionPlanContents);
		for(ConstructionPlanContent planContent : constructionPlanContents) {
			ConstructionUtilService.isAddSuccess(planContent.getId());
		}
	}
	
	/**
	 * @Description: 增加设备关联信息
	 * @Title: addPlanDevice 
	 * @param @param planAddParam 
	 * @return void
	 * @throws
	 */
	public void addPlanDevice(PlanAddParam planAddParam) {
		if(planAddParam.getDeviceIds() == null
				|| planAddParam.getDeviceIds().size() == 0) {
			return;
		}
		int result = constructionPlanDeviceMapper.insertByPlan(planAddParam);
		if(result != planAddParam.getDeviceIds().size()){
			throw new CustomException(ConstructionResultEnum.FLOW_ADD_ERROR);
		}
	}
	
	/**
	 * @Description: id为空是新增，不为空是修改
	 * @Title: addOrUpdatePlan 
	 * @param @param planAddParam
	 * @param @return 
	 * @return WholeFlowInfo
	 * @throws
	 */
	public WholeFlowInfo setOrUpdatePlan(PlanAddParam planAddParam, User user) {
		return planAddParam.getPlanId()==null?setPlan(planAddParam, user):updatePlan(planAddParam, user);
	}
	
	/**
	 * @Description: 补全参数
	 * @Title: patchPlan 
	 * @param @param planAddParam
	 * @param @param user 
	 * @return void
	 * @throws
	 */
	public void patchPlan(ConstructionPlan constructionPlan, User user) {
		ConstructionPlan existPlan = constructionPlanMapper.selectPlanByFlowId(constructionPlan.getFlowId());
		if(existPlan != null) {
			constructionPlan.setOperator(existPlan.getOperator());
		}
		
		if(StringUtils.isEmpty(constructionPlan.getOperator())) {
			constructionPlan.setOperator(String.valueOf(user.getUserId()));
		}else {
			constructionPlan.setOperator(ConstructionUtilService.synthesisString(constructionPlan.getOperator(),",",String.valueOf(user.getUserId())));
		}
		constructionPlan.setUpdateBy(user.getUserId());
		constructionPlan.setUpdateDate(new Date());
	}
	
	/**
	 * @Description: 根据流程查询计划
	 * @Title: getConstructionPlan 
	 * @param @param flowId
	 * @param @return    设定文件 
	 * @return ConstructionPlan    返回类型 
	 * @throws
	 */
	public ConstructionPlan getConstructionPlan(Integer flowId) {
		return constructionPlanMapper.selectPlanByFlowId(flowId);
	}
	
	/**
	 * @Description: 根据流程ID查询今日施工计划内容
	 * @Title: getTodayContentByFlowId 
	 * @param @param flowId
	 * @param @return    设定文件 
	 * @return String    返回类型 
	 * @throws
	 */
	public String getTodayContentByFlowId(Integer flowId) {
		return constructionContentMapper.getTodayContentByFlowId(flowId);
	}
	
}
